/* Copyright (c) 2009-2010, Sean A.O. Harney <sharney3@gmail.com> */

#include "omf.h"


// expects already evaled leaf expr of type INT for 1st arg
//expects already evaled leaf expr of type INT for 2nd arg
// returns read string (for now also possibly will have list option 
EXPR_P builtin_func_read(EXPR_P expr_fd, EXPR_P expr_n)
{
    if (expr_fd->u.leaf.type != LEAF_INT)
	fatal_error_println
	    ("OMF built-in function read() expects INT expr as 1st argument.");

    //if (expr_data->u.leaf.type != LEAF_STRING)
//      fatal_error_println
//          ("OMF built-in function open() expects STRING expr as 2nd argument.");

    INTVAL_P iv = expr_fd->u.leaf.val.int_val;	//TODO: move to util func to check if positive also as in sleep.c
    int fd = iv->ulong_val;

    iv = expr_n->u.leaf.val.int_val;	//TODO: move to util func to check if positive also as in sleep.c
    int n = iv->ulong_val;

    char *str = checked_malloc(n);
    int rr, total = 0;

    while (1)
      {
	  rr = read(fd, str + total, n - total);
	  if (rr < 0)
	      fatal_error_perror("read()");	// NOTE: should be fatal or perhaps just return -1 so as not to end calling program?? FIXME
	  if (rr == 0)
	      break;

	  total += rr;
	  if (total >= n)	// NOTE: shouldn't ever be >=, == would have been ok
	      break;
      }

    str[n - 1] = '\0';

    return new_expr_leaf_string(str);
}
